break x:20 if strcmp(y, "hello") == 0
(gdb) display a
1: a = 32767
(gdb) display b
2: b = 0
(gdb) display c
3: c = 0
(gdb) undisplay 2
(gdb) step
6 b = 2;
1: a = 1
3: c = 0
ptype
In C,
p arr[1][3]
Use the following command
printf "%d,%d\n", a, b
Each time your program performs a function call, information about the call is generated. The information is saved in a block of data called a stack frame. The stack frames are allocated in a region of memory called the call stack.
A backtrace is a summary of how your program got where it is. It shows one line per frame, for many frames, starting with the currently executing frame (frame zero), followed by its caller (frame one), and on up the stack.
backtrace
or bt
: Print a backtrace of the
entire stack: one line per frame for all frames in the stack.When your program fails during the runtime, a core file would be
dumped out if ulimit -c unlimited
is already executed.
Then gdb your_program
even if the command to run your
program is gdb --args your_program input_file
. Remember
that .gdbinit
file should be not presented. Otherwise,
gdb
would follow the commands in .gdbinit
to
run. When gdb
starts, type core core.114172
to
load the core file. Then bt
shows the backtrace.
Use frame num
to go to that frame.
You need to enable logging.
(gdb) set logging on
You can tell it which file to use.
(gdb) set logging file my_god_object.log
And you can examine current logging configuration.
(gdb) show logging
set print elements number-of-elements
Set a limit on how many elements of an array GDB will print. If GDB is printing a large array, it stops printing after it has printed the number of elements set by the set print elements command. This limit also applies to the display of strings. When GDB starts, this limit is set to 200. Setting number-of-elements to zero means that the printing is unlimited.
hexdump
$ hexdump -v -n 28 -e '1/4 "%08d " "\n"' Restart_files/out.149403.done.rst
00000004
00000005
00000005
00982600
00000027
-0000001
00149403
Explanations
-v
outputs all the content and does not collapse
duplicates-n 28
outputs 28 bytes. Note that integer-32 is 32 bits
or say 4 bytes. Thus 28 bytes means 7 integer-32 numbers.-e '1/4 "%08d " "\n"'
specifies the output format.
1/4
means that the iteration count is 1
and
the byte count is 4
. Thus the number of bytes to be
formatted as a group is 4
. "%08d " "\n"
is the
C printf
format notation. Note that 4/1
does
not work as 1/4
.p usp_ngb(1, 1, ws)
$1 = 7.4697350049059708
p &usp_ngb(1, 1, ws)
$2 = (PTR TO -> ( real(kind=8) )) 0x7fffffff7af0
x/xg &usp_ngb(1, 1, ws)
0x7fffffff7af0: 0x401de102368f6e20
Use this website IEEE-754
Floating-Point Conversion: From 64-bit Hexadecimal Representation To
Decimal Floating-Point to see that 0x401de102368f6e20
is 7.4697350049059710
.
For the format, refer to 10.6 Examining Memory and 10.5 Output Formats.
watch *0x10793ad0
(gdb) p "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
$6 = 'a' <repeats 30 times>
(gdb) set print repeats 0
(gdb) p "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
$7 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
(gdb) set print repeats 10
(gdb) p "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
$8 = 'a' <repeats 30 times>
It’s really difficult. Link
For now, I cannot see the difficulty.
The reason is that GDB has no debug info about the math function.
Use info func sqrt
to check the available math
functions.
Usually __sqrt
is available in GDB.
(gdb) p (double) sin(4.0)
$16 = -0.7568024953079282
(gdb) p (float) sin(4.0)
$17 = -1.98266328e+18
(gdb) p (double) sqrt(4.0)
$18 = 2
(gdb) p (float) sqrt(4.0)
$19 = 0
Note you should use double
as the type of the return
value.
Use gdb to debug Fortran program. Normally, you cannot print correctly the values of 16-bytes floating number.
You can examine the memory by the following commands.
(gdb) p &(xy_qp(2))
$31 = (PTR TO -> ( real(kind=16) )) 0x7fffffffc410
(gdb) x/2xg 0x7fffffffc410
0x7fffffffc410: 0x0000000000000000 0xbfff000000000000
xy_qp(2)
is actually -1.0
in 16-bytes
format.x/2xg
, the first x
is the command of
examining the content of a memory address, the second x
is
the format of hex, g
is the unit size as giant word
(8-bytes) and 2
means repeating twice.x/2xg
gives reversed order of the split parts. The
real content is actually
0xbfff000000000000 0x0000000000000000
,
i.e. 0xbfff0000000000000000000000000000
Compile gdb source codes as follows,
./configure --prefix=/home/jcshi/Softwares/gdb-8.3.1 --with-python=/home/jcshi/Softwares/Python/bin/python3
make -j 4
make install
Note: If python is compiled from source codes by
--enable-shared
, configuring gdb will complain that
no usable python
. I tried to debug the configure script of
gdb, but I failed. So I turn back to re-compile python without
--enable-shared
. However, --enable-shared
seems to be required by pyinstaller
. Maybe I should use a
virtual environment for pyinstaller
.
Load python script in .gdbinit
:
source python_script.py
from os.path import join
import gdb
def read2DMat(in_fpath):
= open(in_fpath,"r")
f = f.readlines()
content = [[]]
data_mat for i in range(len(content)):
= content[i].strip()
line_str = line_str.split(',')
val_list for j in range(len(val_list)):
= float(val_list[j])
val
data_mat[i].append(val)if( i < len(content)-1 ):
data_mat.append([])return data_mat
= '/home/jcshi/code_ref/cases/naca0012/viscous'
ref_dir = [23,24,25,64]
nc_list for nc in nc_list:
= "Q_nc%d.dat"%(nc-1)
ref_q_fname = join(ref_dir, ref_q_fname)
ref_q_fpath = "grid_base_mod::cell(%d)%%beg_sp"%(nc)
gdb_var_str = gdb.parse_and_eval(gdb_var_str)
beg_sp = "grid_base_mod::cell(%d)%%end_sp"%(nc)
gdb_var_str = gdb.parse_and_eval(gdb_var_str)
end_sp # Read in the data
= read2DMat(ref_q_fpath)
ref_q_data # gdb execute cmd
for isp in range(beg_sp,end_sp+1):
for iq in range(4):
= "set cdof%%v(%d,%d)=%23.15e"%(iq+1,isp,ref_q_data[isp-beg_sp][iq])
gdb_cmd_str gdb.execute( gdb_cmd_str )
ptrace operation not permitted
using GDB in dockerExit and run a new docker with the following option,
docker run --cap-add=SYS_PTRACE